package com.kellycheung.chicken_go_go;

import java.util.ArrayList;
import android.graphics.Canvas;
import android.graphics.Paint;

import com.kellycheung.chicken_go_go.GTouchPoint.TouchAction;
import com.kellycheung.chicken_go_go.GameScene.GameSceneStatus;

public class GMenu {
	public class GMenuRow {
		protected GMenu gmParent;
		protected GRectangle grBound;
		
		protected ArrayList<BaseObject> alboMenuItem;
		
		protected int iCol;
		
		public GMenuRow( GMenu p_gm , int p_iCol , float p_fRight , float p_fUp , float p_fLeft , float p_fDown ) {
			this.gmParent = p_gm;
			this.iCol = p_iCol;
			this.grBound = new GRectangle( p_fRight , p_fUp , p_fLeft , p_fDown );
			this.alboMenuItem = new ArrayList<BaseObject>();
		}
		
		public void destroy() {
			try {
				if ( this.alboMenuItem != null ) {
					for ( BaseObject bo : this.alboMenuItem ) {
						if ( bo != null ) {
							bo.destroy();
						}
					}
					
					this.alboMenuItem.clear();
					this.alboMenuItem = null;
				}
				
				this.grBound = null;
				this.gmParent = null;
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.destroy" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void addMenuItem( BaseObject p_bo ) {
			try {
				if ( p_bo != null ) {
					float fCellWidth = this.grBound.getWidth() / (float)this.iCol;
					float fCellHeight = this.grBound.getHeight();
					
					float fPosX = this.grBound.fLeft + fCellWidth/2f + fCellWidth*(this.alboMenuItem.size()%this.iCol);
					float fPosY = this.grBound.fUp + fCellHeight/2f;
					
					p_bo.gcCoord.set( fPosX , fPosY );
					if ( p_bo instanceof GameObject ) {
						((GameObject)p_bo).setBound();
					}
				
					p_bo.gssAllowStatus = this.gmParent.gssAllowStatus;
				}
				
				this.alboMenuItem.add( p_bo );
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.addMenuItem" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void draw( Canvas p_c , Paint p_p ) {
			try {
				for ( BaseObject bo : this.alboMenuItem ) {
					if ( bo != null ) {
						bo.draw( p_c , p_p );
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.addMenuItem" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void processInput( TouchAction p_ta ) {
			try {
				for ( BaseObject bo : this.alboMenuItem ) {
					if ( bo != null ) {
						if ( bo instanceof ClickableObj ) {
							((ClickableObj)bo).processInput( p_ta );
						}
					}
				} 
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.processInput" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void preGameLoopLogic() {
			try {
				for ( BaseObject bo : this.alboMenuItem ) {
					if ( bo != null ) {
						bo.preGameLoopLogic();
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.preGameLoopLogic" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void gameLoopLogic() {
			try {
				for ( BaseObject bo : this.alboMenuItem ) {
					if ( bo != null ) {
						bo.gameLoopLogic();
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.gameLoopLogic" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void postGameLoopLogic() {
			try {
				for ( BaseObject bo : this.alboMenuItem ) {
					if ( bo != null ) {
						bo.postGameLoopLogic();
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GMenuRow.postGameLoopLogic" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
	}
	protected GameScene gsMain;
	protected GRectangle grBound;
	protected GMenu gmPrev;
	
	protected ArrayList<BaseObject> alboMenuBg;
	protected ArrayList<GMenuRow> algmrMenuItemRow;
	protected ArrayList<BaseObject> alboMenuFg;
	
	protected int iRow;
	protected GameSceneStatus gssAllowStatus;
	
	protected boolean isShowing;
	protected int iPage;
	
	public GMenu( GameScene p_gs , float p_fX , float p_fY , float p_fW , float p_fH , int p_iRow , GameSceneStatus p_gss ) {
		try {
			this.gsMain = p_gs;
			this.grBound = new GRectangle( p_fX+p_fW , p_fY , p_fX , p_fY+p_fH );
			this.iRow = p_iRow;
			this.gssAllowStatus = p_gss;
			
			this.isShowing = false;
			this.alboMenuBg = new ArrayList<BaseObject>();
			this.algmrMenuItemRow = new ArrayList<GMenuRow>();
			this.alboMenuFg = new ArrayList<BaseObject>();
			
			this.iPage = 0;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void destroy() {
		try {
			if ( this.alboMenuBg != null ) {
				for ( BaseObject bo : this.alboMenuBg ) {
					if ( bo != null ) {
						bo.destroy();
					}
				}
				this.alboMenuBg.clear();
				this.alboMenuBg = null;
			}
			
			if ( this.alboMenuFg != null ) {
				for ( BaseObject bo : this.alboMenuFg ) {
					if ( bo != null ) {
						bo.destroy();
					}
				}
				this.alboMenuFg.clear();
				this.alboMenuFg = null;
			}
			
			if ( this.algmrMenuItemRow != null ) {
				for ( GMenuRow gmr : this.algmrMenuItemRow ) {
					if ( gmr != null ) {
						gmr.destroy();
					}
				}
				this.algmrMenuItemRow.clear();
				this.algmrMenuItemRow = null;
			}
			
			this.gmPrev = null;
			this.grBound = null;
			this.gsMain = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void showMenu() {
		try {
			this.showMenu( true );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.showMenu" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void showMenu( boolean p_bHidePrev ) {
		try {
			this.gmPrev = this.gsMain.gmNowShowing;
			
			if ( this.gmPrev != null && p_bHidePrev == true ) {
				this.gmPrev.isShowing = false;
			}
			
			this.isShowing = true;
			this.gsMain.gssStatus = this.gssAllowStatus;
			this.gsMain.gmNowShowing = this;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.showMenu(boolean)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public GMenu hideMenu() {
		try {
			GMenu gmPrev = this.gmPrev;
			
			this.isShowing = false;
			
			this.gsMain.gmNowShowing = this.gmPrev;
			
			for ( GMenuRow gmr : this.algmrMenuItemRow ) {
				if ( gmr != null ) {
					for ( BaseObject bo : gmr.alboMenuItem ) {
						if ( bo != null ) {
							if ( bo instanceof ClickableObj ) {
								((ClickableObj)bo).resetValue();
							}
						}
					}
				}
			}
			
			if ( this.gmPrev != null ) {
				for ( GMenuRow gmr : this.gmPrev.algmrMenuItemRow ) {
					if ( gmr != null ) {
						for ( BaseObject bo : gmr.alboMenuItem ) {
							if ( bo != null ) {
								if ( bo instanceof ClickableObj ) {
									((ClickableObj)bo).resetValue();
								}
							}
						}
					}
				}
				
				this.gmPrev.isShowing = true;
				this.gsMain.gssStatus = gmPrev.gssAllowStatus;
			}
			else {
				this.gsMain.gssStatus = this.gsMain.gssStatusNormal; 
			}
			
			this.gmPrev = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.hideMenu" );
			GameUtil.ErrorHandler( this , p_e );
		}
				
		return this.gmPrev;
	}
	
	public void addMenuBg( BaseObject p_bo ) {
		try {
			p_bo.gssAllowStatus = this.gssAllowStatus;
			this.alboMenuBg.add( p_bo );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.addMenuBg" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addMenuFg( BaseObject p_bo ) {
		try {
			p_bo.gssAllowStatus = this.gssAllowStatus;
			this.alboMenuFg.add( p_bo );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.addMenuFg" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addNewMenuRow( int p_iCol ) {
		try {
			float fWidth = this.grBound.getWidth();
			float fHeight = this.grBound.getHeight() / (float)this.iRow;
			float fUp = this.grBound.fUp + fHeight * ((float)this.algmrMenuItemRow.size() % this.iRow);
			float fLeft = this.grBound.fLeft;
			
			this.algmrMenuItemRow.add( new GMenuRow( this , p_iCol , fLeft+fWidth , fUp , fLeft , fUp+fHeight ) );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.addNewMenuRow" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addMenuItem( BaseObject p_bo ) {
		try {
			this.algmrMenuItemRow.get( this.algmrMenuItemRow.size()-1 ).addMenuItem( p_bo );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.addMenuItem" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void draw( Canvas p_c , Paint p_p ) {
		try {
			GMenuRow gmr;
			
			if ( this.isShowing ) {
				for ( BaseObject bo : this.alboMenuBg ) {
					if ( bo != null ) {
						bo.draw( p_c , p_p );
					}
				}
				
				for ( int i = this.iPage*this.iRow ; i < (this.iPage+1)*this.iRow && i < this.algmrMenuItemRow.size() ; i++ ) {
					gmr = this.algmrMenuItemRow.get( i );
					if ( gmr != null ) {
						gmr.draw( p_c , p_p );
					}
				}
				
				for ( BaseObject bo : this.alboMenuFg ) {
					if ( bo != null ) {
						bo.draw( p_c , p_p );
					}
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.draw" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void processInput( TouchAction p_ta ) {
		try {
			GMenuRow gmr;
			
			if ( this.isShowing ) {
				for ( BaseObject bo : this.alboMenuBg ) {
					if ( bo != null ) {
						if ( bo instanceof ClickableObj ) {
							((ClickableObj)bo).processInput( p_ta );
						}
					}
				}
				
				for ( int i = this.iPage*this.iRow ; i < (this.iPage+1)*this.iRow && i < this.algmrMenuItemRow.size() ; i++ ) {
					gmr = this.algmrMenuItemRow.get( i );
					if ( gmr != null ) {
						gmr.processInput( p_ta );
					}
				}
				
				for ( BaseObject bo : this.alboMenuFg ) {
					if ( bo != null ) {
						if ( bo instanceof ClickableObj ) {
							((ClickableObj)bo).processInput( p_ta );
						}
					}
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.processInput" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void preGameLoopLogic() {
		try {
			GMenuRow gmr;
			
			//Collections.sort( this.alboMenuBg );
			for ( BaseObject bo : this.alboMenuBg ) {
				if ( bo != null ) {
					bo.preGameLoopLogic();
				}
			}
			
			for ( int i = this.iPage*this.iRow ; i < (this.iPage+1)*this.iRow && i < this.algmrMenuItemRow.size() ; i++ ) {
				gmr = this.algmrMenuItemRow.get( i );
				if ( gmr != null ) {
					gmr.preGameLoopLogic();
				}
			}
			
			//Collections.sort( this.alboMenuFg );
			for ( BaseObject bo : this.alboMenuFg ) {
				if ( bo != null ) {
					bo.preGameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.preGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void gameLoopLogic() {
		try {
			GMenuRow gmr;
			
			for ( BaseObject bo : this.alboMenuBg ) {
				if ( bo != null ) {
					bo.gameLoopLogic();
				}
			}
			
			for ( int i = this.iPage*this.iRow ; i < (this.iPage+1)*this.iRow && i < this.algmrMenuItemRow.size() ; i++ ) {
				gmr = this.algmrMenuItemRow.get( i );
				if ( gmr != null ) {
					gmr.gameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboMenuFg ) {
				if ( bo != null ) {
					bo.gameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.gameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void postGameLoopLogic() {
		try {
			GMenuRow gmr;
			
			for ( BaseObject bo : this.alboMenuBg ) {
				if ( bo != null ) {
					bo.postGameLoopLogic();
				}
			}
			
			for ( int i = this.iPage*this.iRow ; i < (this.iPage+1)*this.iRow && i < this.algmrMenuItemRow.size() ; i++ ) {
				gmr = this.algmrMenuItemRow.get( i );
				if ( gmr != null ) {
					gmr.postGameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboMenuFg ) {
				if ( bo != null ) {
					bo.postGameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GMenu.postGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
}
